//-----------------------------------------------------------------------------
// author: Jaime Francisco Jaramillo id.9272518
// date: March 23, 2012
//
// -------------
// GanttView.java
//
// Creates a Gantt chart and puts it in a JPanel ready for display.
// This view needs to be given an array of Task objects to create the chart.
//
// NOTE: This class uses two different "Task" classes: 
// (1) org.jfree.data.gantt.Task  
// (2) taskManagerSystem.ModelSubsystem.Task
// 
// This class uses the JFreeChart libraries (http://www.jfree.org/jfreechart/)
//-----------------------------------------------------------------------------

package taskManagerSystem.ViewSubsystem;

import java.awt.GridLayout;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;
import org.jfree.data.time.SimpleTimePeriod;

public class GanttView extends JPanel 
{
	/**
	 *  members
	 */
	private static final long serialVersionUID = 112353276;
	private TaskSeriesCollection collection; 
	private TaskSeries s1; 
	private Vector<taskManagerSystem.ModelSubsystem.Task> data;
	private ChartPanel chartPanel;
	private IntervalCategoryDataset dataset;
	private JFreeChart chart;
	private int numTasks;
	 
	// constructor
    public GanttView()
    {
    	super(new GridLayout(1,0)); 
    	
    	numTasks = 0;
    	
    	// create the task collection
    	collection = new TaskSeriesCollection();
    	s1 = new TaskSeries("");
    	collection.add(s1);
    	
    	// create a new chartPanel
    	chartPanel = new ChartPanel(chart);
    	//chartPanel.setPreferredSize(new java.awt.Dimension(1050, 300));
    	add(chartPanel);
    	
    }

    // cleans up the data vector, refreshes the UI
    public void  clearData()
    {
    	this.data = null;
    	s1.removeAll();
    	this.removeAll();
    	this.repaint();
    	//this.validate();
    }
    
    // gets the data in the gantt view
    public Vector<taskManagerSystem.ModelSubsystem.Task> getData()
    {
    	return data;
    }
    
    // gets the chart
    public ChartPanel getChart()
    {
    	return chartPanel;
    }
    
    // takes and array containing the Task information and creates the dataset used by 
    // the gantt chart
	@SuppressWarnings("unchecked")
	public void setData( Vector<taskManagerSystem.ModelSubsystem.Task> vector )
	{	
		s1.removeAll();
		
		this.data = (Vector<taskManagerSystem.ModelSubsystem.Task>) vector.clone();	
				
		String deadline = "";
		int day, month, year;
		Date endDate = null;
		Date startDate = null;
		
		for(int i=0; i<data.size(); i++)
		{
			deadline = data.elementAt(i).getDeadlineDate();
			
			// if there is no deadline for the given task, do not show in the chart
			if(deadline.isEmpty())
				continue;
			
			// parse deadline date
			month = Integer.parseInt(deadline.substring(0, deadline.indexOf('/'))) -1;
			day = Integer.parseInt(deadline.substring(deadline.indexOf('/')+1, deadline.lastIndexOf('/')));
			year = Integer.parseInt( deadline.substring(deadline.lastIndexOf('/')+1));
			endDate = date(day, month, year);
			
			// calculate start date from deadline-duration
			Calendar cal = Calendar.getInstance();
			cal.set(year, month, day, 0, 0, 0);
			cal.add(Calendar.DAY_OF_MONTH, -data.elementAt(i).getDuration());
			startDate = cal.getTime();
				
			// add the task to the task series
			s1.add(	new Task(data.elementAt(i).getTitle(),
		            new SimpleTimePeriod(startDate, endDate))
			    	);
		}
		
		// if item count too low -> add some "ghost" tasks
		// (prevents the chart looking nasty when only a few tasks are created -- bars looking huge)
		if(s1.getItemCount() < 10 && s1.getItemCount()>=1)
		{
			int numOfGhosts = 10-s1.getItemCount();
			
			for(int i=0; i<numOfGhosts; i++)
			{
				String ghostName= " ";
				for(int k=0; k<=i; k++)
					ghostName += " ";
				
				s1.add( new Task(ghostName,  new SimpleTimePeriod(endDate, endDate)) );  	// create the "ghost" task
			}
		}
		
		// set numTasks
        numTasks = s1.getItemCount();

		// add to the collection -> make the collection the new dataset to be used
        //collection.add(s1);
        dataset = (IntervalCategoryDataset) collection;
	}
	
	public void update()
	{
		// make the chart, add it to chartPanel
		chartPanel.setPreferredSize(new java.awt.Dimension(1030, 30*numTasks));
		chart = createChart(dataset);
		chartPanel.setChart(chart);
		
		// clean up view
		this.removeAll();
        
		// add the chart panel to the GanttView and refresh
		add(chartPanel);
    	this.validate();
	}

    /**
     * Utility method for creating Date objects.
     *
     * @param day  the date.
     * @param month  the month.
     * @param year  the year.
     *
     * @return a date.
     */
    private static Date date(final int day, final int month, final int year) 
    {

        final Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, day, 0, 0, 0);
        final Date result = calendar.getTime();
        return result;
    }
        
    /**
     * Creates a chart.
     * 
     * @param dataset  the dataset.
     * 
     * @return The chart.
     */
    private JFreeChart createChart(final IntervalCategoryDataset dataset) {
        final JFreeChart chart = ChartFactory.createGanttChart(
            "",  // chart title
            "Task",              // domain axis label
            "Date",              // range axis label
            dataset,             // data
            false,                // include legend
            true,                // tooltips
            false                // urls
        );   
        return chart;   
    }
    
    public TaskSeriesCollection getCollection()
    {
    	return collection;
    }
    
    public TaskSeries getSeries()
    {
    	return s1;
    }
}
